package com.ucd.generator.util;

import com.alibaba.fastjson.JSON;
import com.ucd.common.constant.GenConstants;
import com.ucd.common.utils.StringUtils;
import com.ucd.generator.config.GenConfig;
import com.ucd.generator.domain.GenTable;
import com.ucd.generator.domain.GenTableColumn;
import com.ucd.generator.domain.Option;
import org.apache.commons.lang3.RegExUtils;

import java.util.Arrays;
import java.util.List;

/**
 * 代码生成器 工具类
 *
 * @author ucd
 */
public class GenUtils {
    /**
     * 初始化表信息
     */
    public static void initTable(GenTable genTable, String operName) {
        genTable.setClassName(convertClassName(genTable.getTableName()));
        genTable.setPackageName(GenConfig.getPackageName());
        genTable.setModuleName(getModuleName(GenConfig.getPackageName()));
        genTable.setBusinessName(getBusinessName(GenConfig.getPackageName(), genTable.getTableName()));
        genTable.setFunctionName(replaceText(genTable.getTableComment()));
        genTable.setFunctionAuthor(GenConfig.getAuthor());
        genTable.setCreateBy(operName);
    }

    /**
     * 初始化列属性字段
     */
    public static void initColumnField(GenTableColumn column, GenTable table) {
        String dataType = getDbType(column.getColumnType());
        column.setTableId(table.getTableId());
        column.setCreateBy(table.getCreateBy());
        // 设置java字段备注
        String columnComment = column.getColumnComment();
        if (columnComment.contains(GenConstants.DELIMITER)) {
            String realComment = columnComment.substring(0, columnComment.indexOf(GenConstants.DELIMITER));
            column.setColumnComment(realComment);
        }
        // 设置java字段名
        String columnName = column.getColumnName();
        column.setJavaField(StringUtils.toCamelCase(columnName));
        // 设置默认类型
        column.setJavaType(GenConstants.TYPE_STRING);
        column.setHtmlType(GenConstants.HTML_INPUT);
        // 设置时间类型字段
        if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) {
            column.setJavaType(GenConstants.TYPE_DATE);
            column.setHtmlType(GenConstants.HTML_DATETIME);
        } else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) {
            column.setHtmlType(GenConstants.HTML_INPUT);
            String[] str = StringUtils.split(StringUtils.substringBetween(column.getColumnType(), "(", ")"), ",");
            if (str != null && str.length == 2 && Integer.parseInt(str[1]) > 0) {
                // 如果是浮点型 统一用BigDecimal
                column.setJavaType(GenConstants.TYPE_BIGDECIMAL);
            } else if (str != null && str.length == 1 && Integer.parseInt(str[0]) <= 10) {
                // 如果是整形
                column.setJavaType(GenConstants.TYPE_INTEGER);
            } else {
                // 长整形
                column.setJavaType(GenConstants.TYPE_LONG);
            }
        }
        // 插入字段（是否在新增表单页面显示）
        if (!arraysContains(GenConstants.COLUMNNAME_NOT_FORM, columnName) && !columnComment.contains(GenConstants.TAG_NOT_ADD) && !column.isPk()) {
            column.setIsInsert(GenConstants.REQUIRE);
        }
        // 编辑字段（是否在修改表单页面显示）
        if (!arraysContains(GenConstants.COLUMNNAME_NOT_FORM, columnName) && !columnComment.contains(GenConstants.TAG_NOT_EDIT) && !column.isPk()) {
            column.setIsEdit(GenConstants.REQUIRE);
        }
        // 列表字段（是否在table列表中显示）
        if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName) && !columnComment.contains(GenConstants.TAG_NOT_LIST) && !column.isPk()) {
            column.setIsList(GenConstants.REQUIRE);
        }
        // 查询字段（是否支持在table列表搜索块中查询）
        if (columnComment.contains(GenConstants.TAG_SEARCH) && !column.isPk()) {
            column.setIsQuery(GenConstants.REQUIRE);
            // 查询方式,默认EQ（EQ等于、LIKE模糊、BETWEEN日期范围）
            column.setQueryType(GenConstants.QUERY_EQ);
            if (columnComment.contains(GenConstants.TAG_SEARCH_LIKE)) {
                column.setQueryType(GenConstants.QUERY_LIKE);
            } else if (columnComment.contains(GenConstants.TAG_SEARCH_BETWEEN)) {
                column.setQueryType(GenConstants.QUERY_BETWEEN);
            }
        }
        // 字段设置单选框
        if (columnComment.contains(GenConstants.TAG_RADIO)) {
            column.setHtmlType(GenConstants.HTML_RADIO);
            String value = columnComment.substring(columnComment.indexOf("$radio[") + 6, columnComment.lastIndexOf("radio$"));
            List<Option> options = JSON.parseArray(value, Option.class);
            column.setOptions(options);
            column.setOptionStr(value);
        }
        // 字段设置下拉框
        else if (columnComment.contains(GenConstants.TAG_SELECT)) {
            column.setHtmlType(GenConstants.HTML_SELECT);
            String value = columnComment.substring(columnComment.indexOf("$select[") + 7, columnComment.lastIndexOf("select$"));
            List<Option> options = JSON.parseArray(value, Option.class);
            column.setOptions(options);
            column.setOptionStr(value);
        }
        // 字段设置图片上传控件
        else if (columnComment.contains(GenConstants.TAG_IMAGE)) {
            column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD);
        }
        // 字段设置文件上传控件
        else if (columnComment.contains(GenConstants.TAG_FILE)) {
            column.setHtmlType(GenConstants.HTML_FILE_UPLOAD);
        }
        // 字段设置富文本控件
        else if (columnComment.contains(GenConstants.TAG_EDITOR)) {
            column.setHtmlType(GenConstants.HTML_EDITOR);
        }
        // 字段设置文本域控件
        else if (columnComment.contains(GenConstants.TAG_TEXT)) {
            column.setHtmlType(GenConstants.HTML_TEXTAREA);
        }
        // 字段设置复选框控件
        else if (columnComment.contains(GenConstants.TAG_CHECKBOX)) {
            column.setHtmlType(GenConstants.HTML_CHECKBOX);
            String value = columnComment.substring(columnComment.indexOf("$checkbox[") + 9, columnComment.lastIndexOf("checkbox$"));
            List<Option> options = JSON.parseArray(value, Option.class);
            column.setOptions(options);
            column.setOptionStr(value);
        }
        // 字段设置开关控件
        else if (columnComment.contains(GenConstants.TAG_SWITCH)) {
            column.setHtmlType(GenConstants.HTML_SWITCH);
            String value = columnComment.substring(columnComment.indexOf("$switch[") + 7, columnComment.lastIndexOf("switch$"));
            List<Option> options = JSON.parseArray(value, Option.class);
            column.setOptions(options);
            column.setOptionStr(value);
        }
        // 字段设置下拉菜单-数据字典控件
        if (columnComment.contains(GenConstants.TAG_DICT)) {
            String value = columnComment.substring(columnComment.indexOf("$dict[") + 6, columnComment.lastIndexOf("]dict$"));
            column.setDictType(value);
        }
    }

    /**
     * 校验数组是否包含指定值
     *
     * @param arr         数组
     * @param targetValue 值
     * @return 是否包含
     */
    public static boolean arraysContains(String[] arr, String targetValue) {
        return Arrays.asList(arr).contains(targetValue);
    }

    /**
     * 获取模块名
     *
     * @param packageName 包名
     * @return 模块名
     */
    public static String getModuleName(String packageName) {
        int lastIndex = packageName.lastIndexOf(".");
        int nameLength = packageName.length();
        String moduleName = StringUtils.substring(packageName, lastIndex + 1, nameLength);
        return moduleName;
    }

    /**
     * 获取业务名
     *
     * @param packageName 包名
     * @param tableName   表名
     * @return 业务名
     */
    public static String getBusinessName(String packageName, String tableName) {
        String moduleName = getModuleName(packageName);
        String newTableName = tableName.replaceFirst(moduleName + "_", "");
        return StringUtils.toCamelCase(newTableName);
    }

    /**
     * 表名转换成Java类名
     *
     * @param tableName 表名称
     * @return 类名
     */
    public static String convertClassName(String tableName) {
        boolean autoRemovePre = GenConfig.getAutoRemovePre();
        String tablePrefix = GenConfig.getTablePrefix();
        if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) {
            String[] searchList = StringUtils.split(tablePrefix, ",");
            tableName = replaceFirst(tableName, searchList);
        }
        return StringUtils.convertToCamelCase(tableName);
    }

    /**
     * 批量替换前缀
     *
     * @param replacement 替换值
     * @param searchList  替换列表
     * @return
     */
    public static String replaceFirst(String replacement, String[] searchList) {
        String text = replacement;
        for (String searchString : searchList) {
            if (replacement.startsWith(searchString)) {
                text = replacement.replaceFirst(searchString, "");
                break;
            }
        }
        return text;
    }

    /**
     * 关键字替换
     *
     * @param text 需要被替换的名字
     * @return 替换后的名字
     */
    public static String replaceText(String text) {
        return RegExUtils.replaceAll(text, "(?:表|若依)", "");
    }

    /**
     * 获取数据库类型字段
     *
     * @param columnType 列类型
     * @return 截取后的列类型
     */
    public static String getDbType(String columnType) {
        if (StringUtils.indexOf(columnType, "(") > 0) {
            return StringUtils.substringBefore(columnType, "(");
        } else {
            return columnType;
        }
    }

    /**
     * 获取字段长度
     *
     * @param columnType 列类型
     * @return 截取后的列类型
     */
    public static Integer getColumnLength(String columnType) {
        if (StringUtils.indexOf(columnType, "(") > 0) {
            String length = StringUtils.substringBetween(columnType, "(", ")");
            return Integer.valueOf(length);
        } else {
            return 0;
        }
    }
}
